-
-
Notifications
You must be signed in to change notification settings - Fork 651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Address a performance regression from #4230 by deferring new URL
computations.
#4344
Conversation
Next, I'll make a similar chart for the Recurse realm. I expect we might see different levels of effectiveness for some commits than we see on CZO because Recurse has EMAIL_ADDRESS_VISIBILITY_EVERYONE set. But Recurse also has lots of users. |
OK, here's the same thing but on the Recurse realm instead of CZO: Looks like 9ec9e20 (the one for FallbackAvatarURL) is less helpful on Recurse. The "fallback" case kicks in when Looks like 1de50cc is a lot less helpful (if it's helpful at all) on Recurse. I expect that's because Recurse has EMAIL_ADDRESS_VISIBILITY_EVERYONE set, while CZO doesn't. 1de50cc improves the case where the server sends the full Gravatar URL string, which it does if EMAIL_ADDRESS_VISIBILITY_EVERYONE is not set. Looks like 190eb15 is a lot more helpful on Recurse than on CZO. That optimization affects uploaded avatar URLs that are absolute URLs not on the realm. Recurse sends those absolute URLs (it uses the s3 backend), while CZO does not; that's probably why. Looks like, still, nothing's quite as fast as it was before #4230, hmm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for these changes and the detailed timing information!
These all look good to me except the last one, 190eb15, for uploaded avatars -- comments on that one below. I'll go ahead and merge all the others, and then I'll see about trying to write an improved version of that one.
I do think we should be able to continue to speed this up so that the initial load is faster than before #4230, rather than slower. The purpose of the user_avatar_url_field_optional
feature was all about speeding it up, after all. So for the next steps, I'm curious what a profile shows about where the time is going after these changes. We can continue that discussion in the chat thread.
src/utils/avatar.js
Outdated
absoluteOrRelativeUrl.startsWith('/') | ||
? new URL(absoluteOrRelativeUrl, realm) | ||
: absoluteOrRelativeUrl, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of thoughts on this one:
- This logic is completely correct that if the URL string starts with a
/
, it's definitely a relative-URL string (provided it's any kind of valid URL string, and I guess has no fragment). With just a bit more logic, I think we can actually be more specific: we can make it definitely a "path-absolute-URL string", and then we can say${realm.origin}${absoluteOrRelativeURL}
and skip thenew URL
here too. - If the string doesn't start with a slash, it isn't necessarily absolute; it could be one of a few other flavors of relative-URL strings. I think probably a well-behaved server will never want to give us one of those... but I'm not sure of that. So in the spirit of the crunchy shell, I'd like to validate it just a little more to be sure it's absolute, and if it's neither absolute nor the flavor of relative that we expect, then give an error.
How about I try developing a commit for this uploaded-avatar case? I have the URL Standard open, and I think I can make something short and simple that reliably does the small part of it we need here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about I try developing a commit for this uploaded-avatar case? I have the URL Standard open, and I think I can make something short and simple that reliably does the small part of it we need here.
Cool, sounds good, thanks! 🙂
…tor. Specifically, in its static `validateAndConstructInstance` method. In working on the recently merged zulip#4230, we found that calling `new URL` with ordinary input is quite expensive, and so we arranged to not call it when rehydrating. We left the call in `validateAndConstructInstance`, though, thinking we couldn't possibly remove it and still validate the raw server data properly at the edge. When we did some performance benchmarking after zulip#4230 was merged [1], though, we found that `api.registerForEvents` started to take a lot longer after zulip#4230 than before it. Profiling [2] suggested that we could help speed things up if we could just stop calling `new URL` in `validateAndConstructInstance`. Looking closer, thankfully, it's possible and reasonably easy. We would normally avoid string concatenation for URLs entirely, but this is a case where we can do it in a fairly principled way (see the implementation comment in the diff). [1] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/user_avatar_url_field_optional/near/1080919 [2] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/user_avatar_url_field_optional/near/1081240 [3] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/user_avatar_url_field_optional/near/1081253
Just as in the previous commit, we're reducing the computation it takes to process avatar URLs at the edge, just as they're received in bulk (of potentially thousands, on a large realm like CZO) from the server. See Greg's comment for profiling data suggesting this change is indicated [1]. [1] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/user_avatar_url_field_optional/near/1081272
Just as in previous commits, we're reducing the computation it takes to process avatar URLs at the edge, just as they're received in bulk (potentially thousands, on a large realm like CZO) from the server.
Just as in previous commits, we're reducing the computation it takes to process avatar URLs at the edge, just as they're received in bulk (potentially thousands, on a large realm like CZO) from the server.
0798f96
to
1f0e42c
Compare
This follows up on zulip#4344 to address part of the remaining performance regression from zulip#4230. We still construct URL objects in the `get` methods, lazily and memoized; but never up front when simply taking in all the initial data from the server, or the rehydrated data we've stored. This should save a further slice of time in the initial load.
This follows up on #4344 to address part of the remaining performance regression from #4230. We still construct URL objects in the `get` methods, lazily and memoized; but never up front when simply taking in all the initial data from the server, or the rehydrated data we've stored. This should save a further slice of time in the initial load.
Following some profiling with Chrome DevTools, and discussion on CZO, keep going in the direction of deferring
new URL
computations, since the computations done inapi.registerForEvents
have made the initial fetch take quite a lot longer after #4230 than before, and URL computations were observed to be a big part of that in profiling.The above measurements are taken with release builds on my 4+ year-old iPhone 6s running iOS 13.7, on CZO, at notable commits (see the chart's key):
user_avatar_url_field_optional
client capability #4230user_avatar_url_field_optional
.) — Tip of Crunchify shell for avatar URLs, handleuser_avatar_url_field_optional
client capability #4230user_avatar_url_field_optional
client capability #4230; I haven't rebased them atopmaster
, which contains more recent commits.The logging code is the following (also pasted in discussion):
It seems to confirm our expectation that the biggest difference is made by removing the
new URL
inFallbackAvatarURL
'svalidateAndConstructInstance
. That's 9ec9e20 in this revision.Also, removing a
new URL
fromfromUserOrBotData
(which was used to discern which subclass to use) is helpful, as expected. That's 1d3c38a in this revision.Removing two
new URL
s inGravatarURL
'svalidateAndConstructInstance
seems definitely helpful; that's 1de50cc in this revision.The remaining changes in this revision, 720547f and 190eb15...aren't large improvements, it seems. The former might have shortened the time by just a hair; the latter (the tool chose purple, like the before-#4230 measurements, oops) actually ended up with a larger mean than the mean for 1de50cc.
Unfortunately, nothing was able to clearly beat the before-#4230 measurements (the lowest purple line shows its mean), but it's close.